
public class AccuracyTester 
{
	private DistanceMatrix _distMat;
	private double _thres;
	
	int _tp; // matches that are classified as matches
	int _tn; // mismatches that are classified as mismatches
	int _fp; // mismatches that are falsely classified as matches
	int _fn; // matches that are falsely classified as mismatches
		
	public AccuracyTester(DistanceMatrix distMat, double decisionThreshold)
	{
		_thres = decisionThreshold;
		_distMat = distMat;			
		
		calc();
	}
	
	
	/**
	 * Returns the accuracy retrieved from the Distance matrix specified in the constructor
	 * @return accuracy 0...1
	 */
	public double getAccuracy()
	{
		return (double)(_tp+_tn)/(double)(_tp+_tn+_fp+_fn);
	}
	
	/**
	 * Calculates TP, FP, TN and FN-rate and stores it internally
	 */
	private void calc()
	{		
		_fp = _fn = _tp = _tn = 0;
		
		for(int x=0; x<_distMat.getWidth(); x++)
		{
			for(int y=0; y<_distMat.getHeight(); y++)
			{
				if(_distMat.isMatchAt(x, y))
				{
				  // should be a match by Ground truth
					
					if(_distMat.distAt(x, y) > _thres)
					{
						// distance is too high, thus no match => thus false
						_fn++;
					}
					else
					{
						// ok, is beneath the thres, thus classified correctly
						_tp++;
					}
				}
				else
				{
					if(_distMat.distAt(x, y) > _thres)
					{
						// distance is high engouh, thus no match => thus true
						_tn++;
					}
					else
					{
						// ok, enough far away
						_fp++;
					}
				}
			}
		}
	}

}
